-- -------------------------------------------------------------------------
-- Features/World.lua (World Options - Time, Weather & Cleanup)
-- Optimized: Native Caching & Tick Logic
-- -------------------------------------------------------------------------

local module = {}

-- [Dependencies]
local ui = nil
local config = nil
local natives = nil
local lang = nil
local debugger = nil
local features_config = nil

-- [Lua 5.4] <const> for function references
local pcall <const> = pcall
local os_clock <const> = os.clock

-- Module name for config storage
local MODULE_NAME <const> = "World"

-- [Natives Cache]
local N_NETWORK_OVERRIDE_CLOCK_TIME = nil
local N_SET_WEATHER_TYPE_NOW_PERSIST = nil
local N_CLEAR_WEATHER_TYPE_PERSIST = nil

-- [Local State]
local state = {
    subtab_idx = 1,

    -- Time
    lock_time = false,
    time_h = 12,
    time_m = 0,

    -- Weather
    lock_weather = false,
    weather_idx = 1,
    weather_list = {
        "EXTRASUNNY", "CLEAR", "CLOUDS", "SMOG", "FOGGY", "OVERCAST",
        "RAIN", "THUNDER", "CLEARING", "NEUTRAL", "SNOW", "BLIZZARD",
        "SNOWLIGHT", "XMAS", "HALLOWEEN"
    },

    -- Tick cache (avoid redundant per-frame natives)
    last_time_apply = 0,
    last_weather_apply = 0,
    last_applied_time_h = nil,
    last_applied_time_m = nil,
    last_applied_weather_idx = nil,
    last_lock_time = nil,
    last_lock_weather = nil,
}

local function _T(text)
    if _G and _G._T then
        return _G._T(text)
    end
    if lang then
        if lang.get then return lang.get(text) end
        if lang.get_text then return lang.get_text(text) end
    end
    return text
end

-- [Helper] Toast Wrapper
local function show_toast(text, type_str)
    if ui and ui.notify then
        ui.notify(text, type_str or "Info")
    elseif util and util.toast then
        util.toast(text)
    end
end

-- -------------------------------------------------------------------------
-- Config Save/Load Helpers
-- -------------------------------------------------------------------------

local function load_config()
    if not features_config then return end
    local saved = features_config.get_module(MODULE_NAME)
    if not saved then return end
    if saved.lock_time ~= nil then state.lock_time = saved.lock_time end
    if saved.time_h ~= nil then state.time_h = saved.time_h end
    if saved.time_m ~= nil then state.time_m = saved.time_m end
    if saved.lock_weather ~= nil then state.lock_weather = saved.lock_weather end
    if saved.weather_idx ~= nil then state.weather_idx = saved.weather_idx end
end

local function save_config()
    if not features_config then return end
    features_config.set_module(MODULE_NAME, {
        lock_time = state.lock_time,
        time_h = state.time_h,
        time_m = state.time_m,
        lock_weather = state.lock_weather,
        weather_idx = state.weather_idx
    }, true)
end

-- -------------------------------------------------------------------------
-- Module Interface
-- -------------------------------------------------------------------------

--- Initialize the World module with required dependencies
-- @param ui_lib table The UI rendering library
-- @param cfg_lib table The configuration management library
-- @param nat_lib table The native functions library
-- @param lang_lib table The language/translation library
-- @param json_lib table The JSON encoding/decoding library
-- @param lexis_lib table The Lexis API library
-- @param debug_lib table The debugger library
-- @return boolean true on success
function module.init(ui_lib, cfg_lib, nat_lib, lang_lib, _, _, debug_lib)
    ui = ui_lib
    config = cfg_lib
    natives = nat_lib
    lang = lang_lib
    debugger = debug_lib

    assert(ui, "[World] UI library is required")
    assert(config, "[World] Config library is required")

    local ok, fc = pcall(require, "ClickUl.Config.features")
    if ok and fc then features_config = fc end

    if debugger then
        debugger.info("[World] Module initialized successfully")
    end

    if natives then
        N_NETWORK_OVERRIDE_CLOCK_TIME = natives.NETWORK_OVERRIDE_CLOCK_TIME
        N_SET_WEATHER_TYPE_NOW_PERSIST = natives.SET_WEATHER_TYPE_NOW_PERSIST
        N_CLEAR_WEATHER_TYPE_PERSIST = natives.CLEAR_WEATHER_TYPE_PERSIST
    end

    load_config()
    return true
end

--- Background update loop for World module
-- Applies time and weather locks every frame
function module.on_tick()
    if not natives then return end

    local now = os_clock()

    -- Detect toggle changes to force immediate apply when enabled
    if state.lock_time ~= state.last_lock_time then
        state.last_lock_time = state.lock_time
        state.last_time_apply = 0
        state.last_applied_time_h = nil
        state.last_applied_time_m = nil
    end
    if state.lock_weather ~= state.last_lock_weather then
        state.last_lock_weather = state.lock_weather
        state.last_weather_apply = 0
        state.last_applied_weather_idx = nil
    end

    -- Time Lock (with pcall protection)
    if state.lock_time and N_NETWORK_OVERRIDE_CLOCK_TIME then
        if now > state.last_time_apply
            or state.time_h ~= state.last_applied_time_h
            or state.time_m ~= state.last_applied_time_m
        then
            pcall(N_NETWORK_OVERRIDE_CLOCK_TIME, state.time_h, state.time_m, 0)
            state.last_applied_time_h = state.time_h
            state.last_applied_time_m = state.time_m
            state.last_time_apply = now + 1.0
        end
    end

    -- Weather Lock (with pcall protection)
    if state.lock_weather and N_SET_WEATHER_TYPE_NOW_PERSIST then
        local w_name = state.weather_list[state.weather_idx]
        if w_name then
            if now > state.last_weather_apply or state.weather_idx ~= state.last_applied_weather_idx then
                pcall(N_SET_WEATHER_TYPE_NOW_PERSIST, w_name)
                state.last_applied_weather_idx = state.weather_idx
                state.last_weather_apply = now + 2.0
            end
        end
    end
end

--- Draw the World module UI
function module.draw()
    state.subtab_idx = ui.SubTabBar({_T("General"), _T("Other")}, state.subtab_idx or 1)

    if state.subtab_idx == 1 then
        ui.DualColumn(
            function()
                ui.Group(_T("Time Options"), function()
                    state.lock_time = ui.Checkbox(_T("Lock Time"), state.lock_time)
                    state.time_h = ui.Slider(_T("Hour"), state.time_h, 0, 23, 1)
                    state.time_m = ui.Slider(_T("Minute"), state.time_m, 0, 59, 1)

                    if ui.Button(_T("Sync to System Time")) then
                        local d = os.date("*t")
                        state.time_h = d.hour
                        state.time_m = d.min
                        show_toast(_T("Time synced to local clock"), "Success")
                    end
                end)
            end,
            function()
                ui.Group(_T("Weather Options"), function()
                    state.lock_weather = ui.Checkbox(_T("Lock Weather"), state.lock_weather)

                    -- Combo box for weather selection
                    state.weather_idx = ui.Combo(_T("Weather Type"), state.weather_idx, state.weather_list)

                    if not state.lock_weather then
                         ui.Button(_T("Enable Lock to Apply")) -- Helper text
                    end

                    if ui.Button(_T("Reset Weather")) then
                        if N_CLEAR_WEATHER_TYPE_PERSIST then
                            pcall(N_CLEAR_WEATHER_TYPE_PERSIST)
                            state.lock_weather = false
                            show_toast(_T("Weather reset to dynamic"), "Info")
                        end
                    end
                end)
            end
        )
    elseif state.subtab_idx == 2 then
         ui.DualColumn(
            function()
                ui.Group(_T("Misc"), function()
                     ui.Button(_T("More features coming soon"))
                end)
            end,
            function() end
        )
    end
end

function module.on_menu_close()
    save_config()
end

return module
